#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

#include "objects.h"
#include "vm.h"
#include "interpreter.h"

#define MAXINFO (1<<15)

scm *information_addr[MAXINFO];
char *information_info[MAXINFO];

int information_len = 0;

void information_store(scm *addr, char *info)
{
	information_addr[information_len] = addr;
	information_info[information_len] = strdup(info);
	information_len++;
}

char *information_lookup(scm *addr)
{
	for (scm i = 0; i < information_len; i++) {
		if (information_addr[i] == addr)
			return information_info[i];
	}
	
	return "***";
}

void stack_trace()
{
	scm tmp;
	scm gc_stack_ptr;
	scm gc_stack_base_ptr;
	scm *ret_addr;
	
	fprintf(stderr, "=======================\n");
	fprintf(stderr, "STACK TRACE\n");
	
	gc_stack_ptr = reg_rsp;
	gc_stack_base_ptr = reg_rbp;
	
	gc_stack_ptr = gc_stack_base_ptr;
	while(gc_stack_ptr > 0) {
		tmp = stack[gc_stack_ptr--];
		assert(tmp == 0xDEADBEEFDEADBEEF);

		// rbp
		gc_stack_base_ptr = stack[gc_stack_ptr--];
		
		// reg env
		gc_stack_ptr--;

		// ret addr
		ret_addr = PTR_SCM(stack[gc_stack_ptr--]);
		fprintf(stderr, "%s\n", information_lookup(ret_addr));
		
		tmp = stack[gc_stack_ptr--];
		assert(tmp == 0xC0FFEEEEEEEEEEEE);
		
		gc_stack_ptr = gc_stack_base_ptr;
	}
	
	fprintf(stderr, "=======================\n\n");
}

